package com.kcs.common.utils;

import java.io.*;
import java.util.Properties;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


// Referenced classes of package th.co.truecorp.vcare.util:
//            PropertySet

public class XmlUtils
{

    public XmlUtils()
    {
    }

    public static PropertySet xmlBytesToPropertySet(byte input_xml[])
        throws SAXException
    {
        ByteArrayInputStream in = null;
        PropertySet propertyset;
        try
        {
            in = new ByteArrayInputStream(input_xml);
            propertyset = inputSourceToPropertySet(new InputSource(in));
        }
        finally
        {
            if(in != null)
                try
                {
                    in.close();
                }
                catch(Exception e) { }
        }
        return propertyset;
    }

    public static PropertySet xmlStringToPropertySet(String input_xml)
        throws SAXException
    {
        StringReader in = null;
        PropertySet propertyset;
        try
        {
            in = new StringReader(input_xml);
            propertyset = inputSourceToPropertySet(new InputSource(in));
        }
        finally
        {
            if(in != null)
                try
                {
                    in.close();
                }
                catch(Exception e) { }
        }
        return propertyset;
    }

    public static String propertySetToXmlString(PropertySet inputs)
        throws TransformerException
    {
        StringWriter string_writer = null;
        try
        {
            String s;
            try
            {
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = factory.newDocumentBuilder();
                Document document = builder.newDocument();
                Element root = (Element)propertySet2Node(document, inputs);
                TransformerFactory trans_factory = TransformerFactory.newInstance();
                Transformer xml_out = trans_factory.newTransformer();
                Properties props = new Properties();
                props.put("method", "xml");
                xml_out.setOutputProperties(props);
                string_writer = new StringWriter();
                xml_out.transform(new DOMSource(root), new StreamResult(string_writer));
                s = string_writer.toString();
            }
            catch(ParserConfigurationException e)
            {
                throw new TransformerException(e.getMessage(), e);
            }
            catch(TransformerConfigurationException e)
            {
                throw new TransformerException(e.getMessage(), e);
            }
            return s;
        }
        finally
        {
            if(string_writer != null)
                try
                {
                    string_writer.close();
                }
                catch(Exception e) { }
        }
    }

    public static byte[] propertySetToXmlBytes(PropertySet inputs)
        throws TransformerException
    {
        String xml_string = propertySetToXmlString(inputs);
        try
        {
            return xml_string.getBytes("UTF-8");
        }
        catch(UnsupportedEncodingException e)
        {
            throw new TransformerException(e.getMessage(), e);
        }
    }

    protected static PropertySet inputSourceToPropertySet(InputSource in)
        throws SAXException
    {
        try
        {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(in);
            Element root = document.getDocumentElement();
            PropertySet result = node2PropertySet(root);
            return result;
        }
        catch(IOException e)
        {
            throw new SAXException(e.getMessage(), e);
        }
        catch(ParserConfigurationException e)
        {
            throw new SAXException(e.getMessage(), e);
        }
    }

    public static Node propertySet2Node(Document document, PropertySet inputs)
    {
        String typename = inputs.getType();
        typename = typename != null && typename.length() != 0 ? typename : "PropertySet";
        String xmltypename = replaceString(typename, " ", "_spc");
        xmltypename = replaceString(xmltypename, "/", "_slh");
        xmltypename = replaceString(xmltypename, "(", "_lpr");
        xmltypename = replaceString(xmltypename, ")", "_rpr");
        xmltypename = replaceString(xmltypename, "#", "_pnd");
        Element element = document.createElement(xmltypename);
        for(String propname = inputs.getFirstProperty(); propname != null; propname = inputs.getNextProperty())
        {
            String siebelpropname = replaceString(propname, " ", "_spc");
            siebelpropname = replaceString(siebelpropname, "/", "_slh");
            siebelpropname = replaceString(siebelpropname, "(", "_lpr");
            siebelpropname = replaceString(siebelpropname, ")", "_rpr");
            siebelpropname = replaceString(siebelpropname, "#", "_pnd");
            element.setAttribute(siebelpropname, inputs.getProperty(propname));
        }

        String elementvalue = inputs.getValue();
        if(elementvalue != null)
        {
            org.w3c.dom.Text childnode = document.createTextNode(elementvalue);
            element.appendChild(childnode);
        }
        int count = inputs.getChildCount();
        for(int i = 0; i < count; i++)
        {
            PropertySet propchild = inputs.getChild(i);
            Node childnode = propertySet2Node(document, propchild);
            element.appendChild(childnode);
        }

        return element;
    }

    public static PropertySet node2PropertySet(Node inputnode)
    {
        if(inputnode.getNodeType() != 1)
            return null;
        PropertySet current = new PropertySet();
        String xmltypename = inputnode.getNodeName();
        String typename = replaceString(xmltypename, "_spc", " ");
        typename = replaceString(typename, "_slh", "/");
        typename = replaceString(typename, "_lpr", "(");
        typename = replaceString(typename, "_rpr", ")");
        typename = replaceString(typename, "_pnd", "#");
        if(typename != null)
            current.setType(typename);
        if(inputnode.hasAttributes())
        {
            NamedNodeMap attributes = inputnode.getAttributes();
            for(int i = 0; i < attributes.getLength(); i++)
            {
                Node attr = attributes.item(i);
                String attrvalue = attr.getNodeValue();
                String attrname = attr.getNodeName();
                if(attrvalue != null)
                {
                    String propname = replaceString(attrname, "_spc", " ");
                    propname = replaceString(propname, "_slh", "/");
                    propname = replaceString(propname, "_lpr", "(");
                    propname = replaceString(propname, "_rpr", ")");
                    propname = replaceString(propname, "_pnd", "#");
                    current.setProperty(propname, attrvalue);
                }
            }

        }
        if(inputnode.hasChildNodes())
        {
            NodeList childnodelist = inputnode.getChildNodes();
            for(int i = 0; i < childnodelist.getLength(); i++)
            {
                Node childnode = childnodelist.item(i);
                if(childnode.getNodeType() == 1)
                {
                    current.addChild(node2PropertySet(childnode));
                    continue;
                }
                if(childnode.getNodeType() != 3)
                    continue;
                String elementvalue = childnode.getNodeValue();
                if(elementvalue != null)
                    current.setValue(elementvalue);
            }

        }
        return current;
    }

    private static String replaceString(String source, String match_str, String repl_str)
    {
        StringBuffer buffer = new StringBuffer();
        if(source == null)
            return null;
        do
        {
            int pos = source.indexOf(match_str);
            if(pos == -1)
            {
                buffer.append(source);
                break;
            }
            if(pos > 0)
                buffer.append(source.substring(0, pos));
            buffer.append(repl_str);
            source = source.substring(pos + match_str.length());
        } while(true);
        return buffer.toString();
    }
    
    
 
    public static void main(String args[]) {
    	
    	System.out.println("*All".substring(1));
    	
    	/*PropertySet reqH = new PropertySet();
    	reqH.setType("wsInquiryReqHeader");
    	reqH.setProperty("system", "xxx1");
    	reqH.setProperty("serviceid", "xxx2");
    	reqH.setProperty("requestid", "xxx3");
    	
    	PropertySet reqB = new PropertySet();
    	reqB.setType("wsInquiryReqBody");
    	reqB.setProperty("cifNumber", "C001");
    	reqB.setProperty("dealID", "D001");
    	
    	PropertySet req = new PropertySet();
    	req.addChild(reqH);
    	req.addChild(reqB);*/
    	
    	PropertySet reqH = new PropertySet();
    	reqH.setType("wsInquiryResHeader");
    	
    	PropertySet modelH = new PropertySet();
    	modelH.setProperty("system", "S1");
    	modelH.setProperty("serviceID", "S1");
    	modelH.setProperty("requestID",  "S1");
    	modelH.setProperty("respCode",  "S1");
    	modelH.setProperty("respDesc",  "S1");
    	modelH.setProperty("respTime",  "S1");
    	modelH.setProperty("numberOfRec", String.valueOf(2));
    	reqH.addChild(modelH);
    	
    	
    	PropertySet reqB = new PropertySet();
    	reqB.setType("wsInquiryResBody");
    	
    	for (int i = 0; i < 2; i++) {
    		PropertySet model = new PropertySet();
    		model.setProperty("Row",  String.valueOf(i+1));
    		model.setProperty("dealID", "D1");
    		model.setProperty("parentID", "D1");
    		model.setProperty("cifNumber", "D1");
    		model.setProperty("custName", "D1");
    		model.setProperty("transType", "D1");
    		model.setProperty("buySell", "D1");
    		model.setProperty("dealDate", "D1");
    		model.setProperty("valueDate", "D1");
    		model.setProperty("ccy1", "D1");
    		model.setProperty("dealAmt1", "D1");
        	model.setProperty("exchRate", "D1");
        	model.setProperty("ccy2", "D1");
        	model.setProperty("equiAmt", String.valueOf(100));
        	model.setProperty("outstdAmt", String.valueOf(105));
        	model.setProperty("instrumentType", "D1");
        	model.setProperty("branch", "D1");
        	model.setProperty("comments", "D1");
        	model.setProperty("makerID", "D1");
        	model.setProperty("ibcCode", "D1");
        	model.setProperty("documentType", "D1");
        	model.setProperty("lastModifyDate", "D1");
        	
        	reqB.addChild(model);
		}
    	
   	
    	PropertySet req = new PropertySet();
    	req.addChild(reqH);
    	req.addChild(reqB);
    	
   	
    	String enc;
		try {
			enc = XmlUtils.propertySetToXmlString(req);
			System.out.println(enc);
		} catch (TransformerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
         
    }
   

}
